package com.smallkingson.ylib.core.utils;

import android.content.ContentProviderOperation;
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.provider.ContactsContract;
import android.text.TextUtils;

import com.smallkingson.ylib.core.Yr;

import java.io.Serializable;
import java.util.ArrayList;

/**
 * Created by Administrator on 2016/2/15.
 * 通讯录相关操作的工具类
 * */
public class YContacts {

    private static final String COLUMN_CONTACT_ID = ContactsContract.Data.CONTACT_ID;
    private static final String COLUMN_RAW_CONTACT_ID = ContactsContract.Data.RAW_CONTACT_ID;
    private static final String COLUMN_MIMETYPE = ContactsContract.Data.MIMETYPE;
    private static final String COLUMN_NAME = ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME;
    private static final String COLUMN_NUMBER = ContactsContract.CommonDataKinds.Phone.NUMBER;
    private static final String COLUMN_NUMBER_TYPE = ContactsContract.CommonDataKinds.Phone.TYPE;
    private static final String COLUMN_EMAIL = ContactsContract.CommonDataKinds.Email.DATA;
    private static final String COLUMN_EMAIL_TYPE = ContactsContract.CommonDataKinds.Email.TYPE;
    private static final String MIMETYPE_STRING_NAME = ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE;
    private static final String MIMETYPE_STRING_PHONE = ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE;
    private static final String MIMETYPE_STRING_EMAIL = ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE;

    public static Contact deleteContactByPhone(Context context, String phoneNum) {
        ContentResolver contentResolver = context.getContentResolver();
        ArrayList<Contact> phoneContacts = getPhoneContacts(context);

        if (phoneContacts == null || phoneContacts.size() == 0) {
            return null;
        }
        ArrayList<Contact> delContacts = new ArrayList<Contact>();
        for (Contact contact : phoneContacts) {
            if (contact.getNumber().trim().equals(phoneNum.trim())) {
                Yr.i("相同号码：", contact);
                delContacts.add(contact);
            }
        }
        if (delContacts.size() == 0) {
            return null;
        }
        for (Contact contact : delContacts) {
            ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
            // delete contact
            ops.add(ContentProviderOperation
                    .newDelete(ContactsContract.RawContacts.CONTENT_URI)
                    .withSelection(
                            ContactsContract.RawContacts.CONTACT_ID + "="
                                    + contact.getContact_id(), null).build());
            // delete contact information such as phone number,email
            ops.add(ContentProviderOperation
                    .newDelete(ContactsContract.Data.CONTENT_URI)
                    .withSelection(
                            ContactsContract.Data.CONTACT_ID + "="
                                    + contact.getContact_id(), null).build());
            Yr.d("delete contact: " + contact.getName());

            try {
                contentResolver.applyBatch(ContactsContract.AUTHORITY, ops);
                Yr.d("delete contact success");
            } catch (Exception e) {
                Yr.d("delete contact failed");
                Yr.e(e.getMessage());
            }
        }
        return delContacts.get(0);
    }

    public static ArrayList<Contact> getPhoneContacts(Context context) {
        ArrayList<Contact> allContacts = new ArrayList<Contact>();

        Cursor phoneCursor = context.getContentResolver().query(
                ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                new String[] { "_id", "display_name", "data1", "contact_id",
                        "raw_contact_id", "data3", "photo_id", "data2",
                        "sort_key" }, null, null,
                "sort_key COLLATE LOCALIZED ASC");
        if ((phoneCursor == null) || (phoneCursor.getCount() == 0)) {
        }
        int PHONES_NUMBER_INDEX = phoneCursor.getColumnIndex("data1");
        int PHONES_DISPLAY_NAME_INDEX = phoneCursor
                .getColumnIndex("display_name");
        int PHONES_RAW_CONTACT_ID = phoneCursor
                .getColumnIndex("raw_contact_id");
        int PHONES_CONTACT_ID = phoneCursor.getColumnIndex("contact_id");
        int PHONES_ID = phoneCursor.getColumnIndex("_id");
        int PHONES_LABEL = phoneCursor.getColumnIndex("data3");
        int PHONES_PHOTO_ID = phoneCursor.getColumnIndex("photo_id");
        int PHONES_TYPE = phoneCursor.getColumnIndex("data2");
        int SORT_KEY_INDEX = phoneCursor.getColumnIndex("sort_key");
        if (phoneCursor.getCount() > 0) {
            while (phoneCursor.moveToNext()) {
                String phoneNumber = phoneCursor.getString(PHONES_NUMBER_INDEX);
                if (!TextUtils.isEmpty(phoneNumber)) {
                    String contactName = phoneCursor
                            .getString(PHONES_DISPLAY_NAME_INDEX);
                    String sortKey = phoneCursor.getString(SORT_KEY_INDEX);
                    String type = "";

                    String raw_contact_id = phoneCursor
                            .getString(PHONES_RAW_CONTACT_ID);
                    String contact_id = phoneCursor
                            .getString(PHONES_CONTACT_ID);
                    String _id = phoneCursor.getString(PHONES_ID);
                    String phoneLabel = phoneCursor.getString(PHONES_LABEL);
                    String photo_id = phoneCursor.getString(PHONES_PHOTO_ID);
                    String phoneType = phoneCursor.getString(PHONES_TYPE);

                    Contact contactInfo = new Contact(_id, contactName,
                            phoneNumber, type, sortKey, raw_contact_id,
                            contact_id, phoneLabel, photo_id, phoneType);
                    allContacts.add(contactInfo);
                }
            }
        }
        phoneCursor.close();
        return allContacts;
    }

    public static void addContact(Context context, Contact contact) {
        ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();

        ops.add(ContentProviderOperation
                .newInsert(ContactsContract.RawContacts.CONTENT_URI)
                .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null)
                .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null)
                .build());
        ops.add(ContentProviderOperation
                .newInsert(ContactsContract.Data.CONTENT_URI)
                .withValueBackReference(COLUMN_RAW_CONTACT_ID, 0)
                .withValue(COLUMN_MIMETYPE, MIMETYPE_STRING_NAME)
                .withValue(COLUMN_NAME, contact.getName()).build());
        Yr.d("add name: " + contact.getName());

        if (!contact.getNumber().trim().equals("")) {
            ops.add(ContentProviderOperation
                    .newInsert(ContactsContract.Data.CONTENT_URI)
                    .withValueBackReference(COLUMN_RAW_CONTACT_ID, 0)
                    .withValue(COLUMN_MIMETYPE, MIMETYPE_STRING_PHONE)
                    .withValue(COLUMN_NUMBER, contact.getNumber()).build());
            Yr.d("add number: " + contact.getNumber());
        }
        try {
            context.getContentResolver().applyBatch(ContactsContract.AUTHORITY,
                    ops);
            Yr.d("add contact success.");
        } catch (Exception e) {
            Yr.d("add contact failed.");
            Yr.e(e.getMessage());
        }
    }

    public static class Contact implements Serializable {

        public String name;
        public String number;
        public String simpleNumber;
        public String sortKey;
        public String type;
        public String raw_contact_id;
        public String id;
        public String contact_id;
        public String phoneType;
        public String photo_id;
        public String phoneLabel;
        public boolean isPrivate = true;
        //
        public int nstart;
        public int nend;
        public int pstart;
        public int pend;
        public boolean isCheck;

        public boolean getIsPrivate() {
            return isPrivate;
        }

        public void setIsPrivate(boolean isPrivate) {
            this.isPrivate = isPrivate;
        }

        public Contact() {
        }

        public Contact(String _id, String name, String number, String type,
                       String sortKey, String raw_contact_id, String contact_id,
                       String phoneLabel, String photo_id, String phoneType) {
            this.id = _id;
            this.name = name;
            this.number = number;
            this.type = type;
            this.sortKey = sortKey;
            this.simpleNumber = number;
            this.raw_contact_id = raw_contact_id;
            this.contact_id = contact_id;
            this.phoneLabel = phoneLabel;
            this.photo_id = photo_id;
            this.phoneType = phoneType;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getNumber() {
            return number;
        }

        public void setNumber(String number) {
            this.number = number;
        }

        public String getSimpleNumber() {
            return simpleNumber;
        }

        public void setSimpleNumber(String simpleNumber) {
            this.simpleNumber = simpleNumber;
        }

        public String getSortKey() {
            return sortKey;
        }

        public void setSortKey(String sortKey) {
            this.sortKey = sortKey;
        }

        public String getType() {
            return type;
        }

        public void setType(String type) {
            this.type = type;
        }

        public String getRaw_contact_id() {
            return raw_contact_id;
        }

        public void setRaw_contact_id(String raw_contact_id) {
            this.raw_contact_id = raw_contact_id;
        }

        public String getId() {
            return id;
        }

        public void setId(String _id) {
            this.id = _id;
        }

        public String getContact_id() {
            return contact_id;
        }

        public void setContact_id(String contact_id) {
            this.contact_id = contact_id;
        }

        public String getPhoneType() {
            return phoneType;
        }

        public void setPhoneType(String phoneType) {
            this.phoneType = phoneType;
        }

        public String getPhoto_id() {
            return photo_id;
        }

        public void setPhoto_id(String photo_id) {
            this.photo_id = photo_id;
        }

        public String getPhoneLabel() {
            return phoneLabel;
        }

        public void setPhoneLabel(String phoneLabel) {
            this.phoneLabel = phoneLabel;
        }


        @Override
        public String toString() {
            return "Contact [name=" + name + ", number=" + number
                    + ", simpleNumber=" + simpleNumber + ", sortKey=" + sortKey
                    + ", type=" + type + ", raw_contact_id=" + raw_contact_id
                    + ", id=" + id + ", contact_id=" + contact_id + ", phoneType="
                    + phoneType + ", photo_id=" + photo_id + ", phoneLabel="
                    + phoneLabel + ", isPrivate=" + isPrivate + ", nstart="
                    + nstart + ", nend=" + nend + ", pstart=" + pstart + ", pend="
                    + pend + "]";
        }

        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + ((number == null) ? 0 : number.hashCode());
            return result;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            Contact other = (Contact) obj;
            if (number == null) {
                if (other.number != null)
                    return false;
            } else if (!number.equals(other.number))
                return false;
            return true;
        }
    }
}
